﻿using System.Collections.Generic;
using System.Data;

namespace Autoupdate.Common
{
    public static class Common
    {
        public static List<string> GetLocalFiles(string path, bool skipIgnoreFile = true)
        {
            List<string> tmpfiles = new List<string>();
            Util.FindFiles(path, ref tmpfiles);
            List<string> files = new List<string>();
            foreach (string file in tmpfiles)
            {
                if (skipIgnoreFile && IgnoreFiles.Contains(Util.GetRelativePath(path, file)))
                    continue;
                files.Add(file);
            }
            files.Sort();
            return files;
        }

        public static void CompareFiles(string path, DataTable table, List<string> files, List<int> serverExtraFiles, List<int> serverUpdateFiles, List<int> localExtraFiles, List<int> localUpdateFiles)
        {
            int serverCount = table.Rows.Count;
            int localCount = files.Count;
            // 服务器文件为空，本地文件全部删除
            if (serverCount == 0)
            {
                if (localExtraFiles != null)
                {
                    for (int i = 0; i < files.Count; ++i)
                        localExtraFiles.Add(i);
                }
                return;
            }
            // 本地文件为空，全部从服务器更新文件
            if (localCount == 0)
            {
                if (serverExtraFiles != null)
                {
                    for (int i = 0; i < table.Rows.Count; ++i)
                        serverExtraFiles.Add(i);
                }
                return;
            }
            int serverIndex = 0;
            int localIndex = 0;

            while (serverIndex < serverCount && localIndex < localCount)
            {
                int result = CompareFile(table.Rows[serverIndex][SysUpdateFile.Path].ToString(), Util.GetRelativePath(path, files[localIndex]));
                switch (result)
                {
                    ////源表小则将源表本行加入新增队列，同时移动源表指针
                    case -1:
                        if (serverExtraFiles != null)
                            serverExtraFiles.Add(serverIndex);
                        ++serverIndex;
                        break;
                    ////相同两表同时移动指针
                    case 0:
                        // 文件路径+文件名一致，但MD5值不一样，添加到更新文件中
                        string md5 = Util.GetFileMD5(files[localIndex]);
                        if (table.Rows[serverIndex][SysUpdateFile.MD5].ToString() != md5)
                        {
                            if (serverUpdateFiles != null)
                                serverUpdateFiles.Add(serverIndex);
                            if (localUpdateFiles != null)
                                localUpdateFiles.Add(localIndex);
                        }    
                        ++serverIndex;
                        ++localIndex;
                        break;
                    ////目标表小则将目标表本行加入删除队列，同时移动目标表指针
                    case 1:
                        if (localExtraFiles != null)
                            localExtraFiles.Add(localIndex);
                        ++localIndex;
                        break;
                    default:
                        break;
                }
            }
            //源表到达最后一条，目标表未到达，则目标表剩余行全部加入删除队列
            if (localIndex < localCount)
            {
                if (localExtraFiles != null)
                {
                    for (int i = localIndex; i < localCount; ++i)
                        localExtraFiles.Add(i);
                }                
            }
            //目标表到达最后一条，源表未到达，则源表剩余行全部加入新增队列
            else if (serverIndex < serverCount)
            {
                if (serverExtraFiles != null)
                {
                    for (int i = serverIndex; i < serverCount; ++i)
                        serverExtraFiles.Add(i);
                } 
            }
        }

        //public static void PatchToServerFiles(ref DataTable serverTable, DataTable localTable)
        //{
        //    int serverCount = serverTable.Rows.Count;
        //    int localCount = localTable.Rows.Count;
        //    // 服务器文件为空，本地文件全部删除
        //    if (serverCount == 0)
        //    {
        //        serverTable = localTable.Copy();
        //        return;
        //    }
        //    // 本地文件为空，全部从服务器更新文件
        //    if (localCount == 0)
        //        return;
        //    int serverIndex = 0;
        //    int localIndex = 0;

        //    while (serverIndex < serverCount && localIndex < localCount)
        //    {
        //        int result = CompareFile(serverTable.Rows[serverIndex][SysUpdateFile.Path].ToString(), Util.GetRelativePath(path, files[localIndex]));
        //        switch (result)
        //        {
        //            ////源表小则将源表本行加入新增队列，同时移动源表指针
        //            case -1:
        //                //serverExtraFiles.Add(serverIndex);
        //                ++serverIndex;
        //                break;
        //            ////相同两表同时移动指针
        //            case 0:
        //                // 文件路径+文件名一致，但MD5值不一样，添加到更新文件中
        //                string md5 = Util.GetFileMD5(files[localIndex]);
        //                if (serverTable.Rows[serverIndex][SysUpdateFile.MD5].ToString() != md5)
        //                {
        //                    if (serverUpdateFiles != null)
        //                        serverUpdateFiles.Add(serverIndex);
        //                    if (localUpdateFiles != null)
        //                        localUpdateFiles.Add(localIndex);
        //                }
        //                ++serverIndex;
        //                ++localIndex;
        //                break;
        //            ////目标表小则将目标表本行加入删除队列，同时移动目标表指针
        //            case 1:
        //                localExtraFiles.Add(localIndex);
        //                ++localIndex;
        //                break;
        //            default:
        //                break;
        //        }
        //    }
        //    //源表到达最后一条，目标表未到达，则目标表剩余行全部加入删除队列
        //    if (localIndex < localCount)
        //    {
        //        for (int i = localIndex; i < localCount; ++i)
        //            localExtraFiles.Add(i);
        //    }
        //    //目标表到达最后一条，源表未到达，则源表剩余行全部加入新增队列
        //    else if (serverIndex < serverCount)
        //    {
        //        for (int i = serverIndex; i < serverCount; ++i)
        //            serverExtraFiles.Add(i);
        //    }
        //}

        private static int CompareFile(string left, string right)
        {
            int result = 0;
            if (string.IsNullOrEmpty(left))
                result = string.IsNullOrEmpty(right) ? 0 : -1;
            else
                result = string.IsNullOrEmpty(right) ? 1 : string.Compare(left, right, true); // 不都考虑大小写
            return result;
        }
    }
}
